/*
 * ParetoFrame.java
 *
 * Created on Jan 31, 2012, 8:09:42 PM
 */
package gui;

import chart.ParetoChartPanel;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.DefaultFontMapper;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
import com.toedter.calendar.JDateChooser;
import com.toedter.calendar.JSpinnerDateEditor;
import db.DatabaseManager;
import db.entity.TaperMap;
import db.entity.WCSDataInterface;
import excelexporter.ExcelExporter;
import excelexporter.ParetoChartBean;

import java.awt.Graphics2D;
import java.awt.event.WindowEvent;
import java.awt.geom.Rectangle2D;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;

import util.ErrorMessage;
import util.PropertiesLoader;
import util.SimpleFileFilter;

/**
 *
 * @author suzann
 */
public class ParetoFrame extends javax.swing.JFrame {

    /** Creates new form ParetoFrame */
    public ParetoFrame() {
        //Variables initialisation
        dm = new db.DatabaseManager();
        pcPnl = new ParetoChartPanel();
        
        initComponents();
        setInitData();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        rbgGraphType = new javax.swing.ButtonGroup();
        jPanel1 = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jrbTTV = new javax.swing.JRadioButton();
        jrbTIR = new javax.swing.JRadioButton();
        jrbTaper = new javax.swing.JRadioButton();
        jrbRemoval = new javax.swing.JRadioButton();
        jrbSTIR = new javax.swing.JRadioButton();
        dateFrom = new Date();
        sdmFrom = new SpinnerDateModel(dateFrom, null, null, 11);
        jspFromTime = new javax.swing.JSpinner(sdmFrom);
        jLabel3 = new javax.swing.JLabel();
        jdcFromDate = new JDateChooser(null, null, null, new JSpinnerDateEditor());
        jdcToDate = new JDateChooser(null, null, null, new JSpinnerDateEditor());
        dateTo = new Date();
        sdmTo = new SpinnerDateModel(dateTo, null, null, 11);
        jspToTime = new javax.swing.JSpinner(sdmTo);
        jLabel2 = new javax.swing.JLabel();
        jbtDisplay = new javax.swing.JButton();
        jbtExcel = new javax.swing.JButton();
        jbtPDF = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jList1 = new javax.swing.JList();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setMinimumSize(new java.awt.Dimension(1024, 688));

        rbgGraphType.add(jrbTTV);
        jrbTTV.setText("TTV");
        jrbTTV.setActionCommand("TTV");

        rbgGraphType.add(jrbTIR);
        jrbTIR.setSelected(true);
        jrbTIR.setText("TIR");
        jrbTIR.setActionCommand("TIR");

        rbgGraphType.add(jrbTaper);
        jrbTaper.setText("Taper");
        jrbTaper.setActionCommand("Taper");

        rbgGraphType.add(jrbRemoval);
        jrbRemoval.setText("Removal");
        jrbRemoval.setActionCommand("Removal");

        rbgGraphType.add(jrbSTIR);
        jrbSTIR.setText("STIR");
        jrbSTIR.setActionCommand("STIR");

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGap(15, 15, 15)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(jrbTTV)
                        .addComponent(jrbTIR))
                    .addComponent(jrbRemoval)
                    .addComponent(jrbTaper)
                    .addComponent(jrbSTIR))
                .addContainerGap(18, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jrbTIR)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jrbTTV)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jrbSTIR)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jrbRemoval)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jrbTaper)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        deFrom = new JSpinner.DateEditor(jspFromTime, "hh:mm a");
        jspFromTime.setEditor(deFrom);

        jLabel3.setText("To");

        deTo = new JSpinner.DateEditor(jspToTime, "hh:mm a");
        jspToTime.setEditor(deTo);

        jLabel2.setText("From");

        jbtDisplay.setText("Display");
        jbtDisplay.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtDisplayActionPerformed(evt);
            }
        });

        jbtExcel.setText("Export to Excel");
        jbtExcel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtExcelActionPerformed(evt);
            }
        });

        jbtPDF.setText("Export to PDF");
        jbtPDF.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtPDFActionPerformed(evt);
            }
        });

        jLabel1.setText("Mount ID");

        jList1.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Mount 1", "Mount 2", "Both" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane1.setViewportView(jList1);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(29, 29, 29)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jdcToDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jdcFromDate, javax.swing.GroupLayout.PREFERRED_SIZE, 195, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jspToTime, javax.swing.GroupLayout.PREFERRED_SIZE, 142, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jspFromTime, javax.swing.GroupLayout.PREFERRED_SIZE, 142, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(18, 18, 18)
                        .addComponent(jbtDisplay)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtExcel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtPDF)))
                .addGap(28, 28, 28)
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(47, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jspFromTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel2)
                            .addComponent(jdcFromDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel3)
                            .addComponent(jdcToDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jspToTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jbtDisplay)
                            .addComponent(jbtExcel)
                            .addComponent(jbtPDF))))
                .addContainerGap(33, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(21, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(127, 127, 127))))
        );

        getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_END);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-754)/2, (screenSize.height-507)/2, 754, 507);
    }// </editor-fold>

    private void jbtDisplayActionPerformed(java.awt.event.ActionEvent evt) {                                           
        showPareto();
    }                                          

    private void jbtExcelActionPerformed(java.awt.event.ActionEvent evt) {                                         
        exportToExcel();
    }                                        

    private void jbtPDFActionPerformed(java.awt.event.ActionEvent evt) {                                       
        exportToPDF();
    }                                      

    /****************************************************************************
     * Internal Operations
     ****************************************************************************/
    /**
     * This method sets the initial data for Tend Chart Display at first launch.
     * @param 
     */
    private void setInitData()
    {
        //default value for Date
        Calendar today = Calendar.getInstance();
        
        Calendar yesterday = Calendar.getInstance();
        yesterday.setTimeInMillis(today.getTimeInMillis() - 86400000L);
        
        this.jdcToDate.setDate(today.getTime());
        this.jdcFromDate.setDate(yesterday.getTime());
        
        //initialize the inputs
        graphType = ParetoChartPanel.GRAPH_TIR;
        jrbTIR.setSelected(true);
    }
    
    /**
     * This method get component values and show the Tend Chart.
     * @param 
     */    
    protected void showPareto()
    {   
        if(! validateInput())
    		return ;
        
        //get the inputs
        //1. GraphType
        String actionCommand = rbgGraphType.getSelection().getActionCommand();
        System.out.println("Action command : " + actionCommand);
        
        //2. From DateTime
        Calendar fromTime = Calendar.getInstance();
        fromTime.setTime(sdmFrom.getDate());
        Calendar fromDateTime = Calendar.getInstance();
        fromDateTime.setTime(jdcFromDate.getDate());        
        fromDateTime.set(11, fromTime.get(11));
        fromDateTime.set(12, fromTime.get(12));
        fromDateTime.set(13, fromTime.get(13));
        Date startDate = fromDateTime.getTime();
        System.out.println("From date =" + fromDateTime.getTime());
        
        //3. To DateTime
        Calendar toTime = Calendar.getInstance();
        toTime.setTime(sdmTo.getDate());
        Calendar toDateTime = Calendar.getInstance();
        toDateTime.setTime(jdcToDate.getDate());
        toDateTime.set(11, toTime.get(11));
        toDateTime.set(12, toTime.get(12));
        toDateTime.set(13, toTime.get(13));
        Date endDate = toDateTime.getTime();
        System.out.println("to date =" + toDateTime.getTime());
        
        String graphTitle ="";
        //Determine the graphType
        if (actionCommand.equals("TTV")) 
        {
            graphType = ParetoChartPanel.GRAPH_TTV;
            graphTitle = "AVE TTV Pareto";
        }
        else if (actionCommand.equals("Taper")) 
        {
            graphType = ParetoChartPanel.GRAPH_TAPERSPC;
            graphTitle = "AVE Taper Pareto";
        }
        else if (actionCommand.equals("TIR")) 
        {
            graphType = ParetoChartPanel.GRAPH_TIR;
            graphTitle = "AVE TIR Pareto";
        }
        else if (actionCommand.equals("STIR")) 
        {
            graphType = ParetoChartPanel.GRAPH_STIR;
            graphTitle = "AVE STIR Pareto";
        }
        else if (actionCommand.equals("Removal")) 
        {
            graphType = ParetoChartPanel.GRAPH_REMOVAL;
            graphTitle = "AVE Removal Pareto";
        }
        else
        {
            graphType = ParetoChartPanel.GRAPH_TIR;
            graphTitle = "AVE TIR Pareto";
        }
            
        String mountID = jList1.getSelectedValue().toString();
       
        //*Query to get the objects
        if (graphType == ParetoChartPanel.GRAPH_TTV)
        {
        	if (mountID.equals("Mount 1"))
        		sList = dm.listTTV(1, startDate, endDate);
            else if (mountID.equals("Mount 2"))
        		sList = dm.listTTV(2, startDate, endDate);
            else if (mountID.equals("Both"))
            {
        		sList = dm.listTTV(1, startDate, endDate);
        		sList.addAll(dm.listTTV(2, startDate, endDate));
            }        	
        }
        else if (graphType == ParetoChartPanel.GRAPH_TAPERSPC)
        {
        	if (mountID.equals("Mount 1"))
        		sList = dm.listTaperSPC(1, startDate, endDate);
            else if (mountID.equals("Mount 2"))
        		sList = dm.listTaperSPC(2, startDate, endDate);
            else if (mountID.equals("Both"))
            {
        		sList = dm.listTaperSPC(1, startDate, endDate);
        		sList.addAll(dm.listTaperSPC(2, startDate, endDate));
            }        	
        }
        else if (graphType == ParetoChartPanel.GRAPH_TIR)
        {
        	if (mountID.equals("Mount 1"))
        		sList = dm.listTIR(1, startDate, endDate);
            else if (mountID.equals("Mount 2"))
        		sList = dm.listTIR(2, startDate, endDate);
            else if (mountID.equals("Both"))
            {
        		sList = dm.listTIR(1, startDate, endDate);
        		sList.addAll(dm.listTIR(2, startDate, endDate));
            }        	
        }
        else if (graphType == ParetoChartPanel.GRAPH_STIR)
        {
        	if (mountID.equals("Mount 1"))
        		sList = dm.listSTIR(1, startDate, endDate);
            else if (mountID.equals("Mount 2"))
        		sList = dm.listSTIR(2, startDate, endDate);
            else if (mountID.equals("Both"))
            {
        		sList = dm.listSTIR(1, startDate, endDate);
        		sList.addAll(dm.listSTIR(2, startDate, endDate));
            }        	
        }
        else if (graphType == ParetoChartPanel.GRAPH_REMOVAL)
        {
        	if (mountID.equals("Mount 1"))
        		sList = dm.listRemoval(1, startDate, endDate);
            else if (mountID.equals("Mount 2"))
        		sList = dm.listRemoval(2, startDate, endDate);
            else if (mountID.equals("Both"))
            {
        		sList = dm.listRemoval(1, startDate, endDate);
        		sList.addAll(dm.listRemoval(2, startDate, endDate));
            }        	
        }
        else
        {
        	if (mountID.equals("Mount 1"))
        		sList = dm.listTIR(1, startDate, endDate);
            else if (mountID.equals("Mount 2"))
        		sList = dm.listTIR(2, startDate, endDate);
            else if (mountID.equals("Both"))
            {
        		sList = dm.listTIR(1, startDate, endDate);
        		sList.addAll(dm.listTIR(2, startDate, endDate));
            }        	
        }
        
        System.out.println("List: "+sList.size());
        
                
        //load the Pareto Chart
        pcPnl.loadData(graphType, graphTitle, ((List<WCSDataInterface>)sList));
                
        //place the chart.
        pcPnl.setVisible(true);
        this.getContentPane().add(pcPnl,java.awt.BorderLayout.CENTER);
        this.invalidate();
        this.validate();
    }
    
    private boolean validateInput()
    {    	
    	// VALIDATE BLANK FIELDS
    	boolean blankField = false;
    	String blankField_str = "";
    	if(jdcFromDate.getDate()==null)
    	{
    		blankField_str += "jdcFromDate;";
    		blankField = true;
    	}    	
    	if(jdcToDate.getDate()==null)
    	{
    		blankField_str += "jdcToDate;";
    		blankField = true;
    	}    	
    	if(jList1.getSelectedIndex() == -1)
    	{
    		blankField_str += "Mount ID;";
    		blankField = true;
    	}
    	if(blankField)
    	{
    		String errMsg = "Please fill in the following field: \n" + blankField_str;
    		ErrorMessage.displayError(ErrorMessage.WARNING_ERROR, false, "Validation Error", errMsg);
    		return false;
    	}
    	
        // VALIDATE FROM DATE BEFORE TO DATE
    	Calendar fromTime = Calendar.getInstance();
        fromTime.setTime(sdmFrom.getDate());
        Calendar fromDateTime = Calendar.getInstance();
        fromDateTime.setTime(jdcFromDate.getDate());        
        fromDateTime.set(11, fromTime.get(11));
        fromDateTime.set(12, fromTime.get(12));
        fromDateTime.set(13, fromTime.get(13));
        Date startDate = fromDateTime.getTime();

        Calendar toTime = Calendar.getInstance();
        toTime.setTime(sdmTo.getDate());
        Calendar toDateTime = Calendar.getInstance();
        toDateTime.setTime(jdcToDate.getDate());
        toDateTime.set(11, toTime.get(11));
        toDateTime.set(12, toTime.get(12));
        toDateTime.set(13, toTime.get(13));
        Date endDate = toDateTime.getTime();
		
    	if(! startDate.before(endDate))
    	{
    		String errMsg = "From Date should be a date before To Date.";
    		ErrorMessage.displayError(ErrorMessage.WARNING_ERROR, false, "Validation Error", errMsg);
    		return false;
    	}
    	
    	// Difference between From Data and To Date should be within range in properties file
    	int difference = toDateTime.get(Calendar.DAY_OF_YEAR) - fromDateTime.get(Calendar.DAY_OF_YEAR);
    	
    	if (difference > PropertiesLoader.getParetoMaxRange())
    	{
    		String errMsg = "To Date cannot be "+PropertiesLoader.getParetoMaxRange()+" days after From Date.";
    		ErrorMessage.displayError(ErrorMessage.WARNING_ERROR, false, "Validation Error", errMsg);
    		return false;
    	}    
    	return true;
    }
    /** 
     * THIS SECTION HANDLES THE EXPORT TO EXCEL FUNCTIONALITY,
     * INCLUDING ALL THE ADDITIONAL METHODS AND INNER CLASS NEEDED
     *   
     **/
    private void exportToExcel()
    {
        if(! validateInput())
    		return ;
        
        /*get the inputs*/
        //1. GraphType
        String actionCommand = rbgGraphType.getSelection().getActionCommand();
        System.out.println("Action command : " + actionCommand);
        
        //2. From DateTime
        Calendar fromTime = Calendar.getInstance();
        fromTime.setTime(sdmFrom.getDate());
        Calendar fromDateTime = Calendar.getInstance();
        fromDateTime.setTime(jdcFromDate.getDate());        
        fromDateTime.set(11, fromTime.get(11));
        fromDateTime.set(12, fromTime.get(12));
        fromDateTime.set(13, fromTime.get(13));
        Date startDate = fromDateTime.getTime();
        System.out.println("From date =" + fromDateTime.getTime());
        
        //3. To DateTime
        Calendar toTime = Calendar.getInstance();
        toTime.setTime(sdmTo.getDate());
        Calendar toDateTime = Calendar.getInstance();
        toDateTime.setTime(jdcToDate.getDate());
        toDateTime.set(11, toTime.get(11));
        toDateTime.set(12, toTime.get(12));
        toDateTime.set(13, toTime.get(13));
        Date endDate = toDateTime.getTime();
        System.out.println("to date =" + toDateTime.getTime());
        
        
        //Determine the graphType
        if (actionCommand.equals("TTV")) 
        {
            graphType = ParetoChartPanel.GRAPH_TTV;
        }
        else if (actionCommand.equals("Taper")) 
        {
            graphType = ParetoChartPanel.GRAPH_TAPERSPC;
        }
        else if (actionCommand.equals("TIR")) 
        {
            graphType = ParetoChartPanel.GRAPH_TIR;
        }
        else if (actionCommand.equals("STIR")) 
        {
            graphType = ParetoChartPanel.GRAPH_STIR;
        }
        else if (actionCommand.equals("Removal")) 
        {
            graphType = ParetoChartPanel.GRAPH_REMOVAL;
        }
        
        // Query Database to get the List of WCS Data
        if (graphType == ParetoChartPanel.GRAPH_TTV)
            sList = dm.listTTV(1, startDate, endDate);
        else if (graphType == ParetoChartPanel.GRAPH_TAPERSPC)
            sList = dm.listTaperSPC(1, startDate, endDate);
        else if (graphType == ParetoChartPanel.GRAPH_TIR)
            sList = dm.listTIR(1, startDate, endDate);
        else if (graphType == ParetoChartPanel.GRAPH_STIR)
            sList = dm.listSTIR(1, startDate, endDate);
        else if (graphType == ParetoChartPanel.GRAPH_REMOVAL)
            sList = dm.listRemoval(1, startDate, endDate);
        
        
        // Calculation average value for each row of WCS Data
        // and group the WCS Data according to Polisher Arm
		ArrayList<AverageEntry> sItemAvg = new ArrayList<AverageEntry>();
		
		String stationID;
		Double average;
		int stationNo, armNo, arrayIndex;
		for(int i =0; i<14; i++)
			sItemAvg.add(new AverageEntry());
		
		for(Object sItem_obj : sList)
		{
			if(!(sItem_obj instanceof WCSDataInterface))
				continue;
			
			WCSDataInterface sItem = (WCSDataInterface)sItem_obj;
			// Get the stationID in form of "1L", "2R", "3L", ...
			String dcEl01 = sItem.getDCElement();
			String dcEl02="";
			switch(graphType)
			{
			case ParetoChartPanel.GRAPH_TTV: dcEl02 = dcEl01.replace("TTV", "TP");  break;
			case ParetoChartPanel.GRAPH_TIR: dcEl02 = dcEl01.replace("TIR", "TP"); break;
			case ParetoChartPanel.GRAPH_STIR: dcEl02 = dcEl01.replace("STIR", "TP");  break;
			case ParetoChartPanel.GRAPH_REMOVAL: dcEl02 = dcEl01.replace("PREMDS", "TP");  break;
			case ParetoChartPanel.GRAPH_TAPERSPC: dcEl02 = dcEl01; break;
			}
			stationID = mapDCElement(dcEl02);
			
			// shortcut to find the correct array slot for average value.
			stationNo = Integer.parseInt(stationID.substring(0,1));
			armNo = stationID.charAt(1)== 'L' ? 1 : 2;			
			arrayIndex = (stationNo -1)*2 + (armNo -1);
			
			average = (sItem.getValue1() + sItem.getValue2() + sItem.getValue3() + sItem.getValue4())/4;
			
			if (sItemAvg.get(arrayIndex).armID.equals(""))
				sItemAvg.get(arrayIndex).armID = "A"+stationID;
			
			sItemAvg.get(arrayIndex).average += average;
		}
		
		// Calculate the final average of each Polisher Arm and export to excel
		Collections.sort((List<AverageEntry>)sItemAvg, new AvgEntryComparator());
		ArrayList<ParetoChartBean> excelBeanLS = new ArrayList<ParetoChartBean>();
		for(int i=0; i<14; i++)
		{
			double finalAverage = sItemAvg.get(i).average / sItemAvg.size();
			
			ParetoChartBean excelBean = new ParetoChartBean();
			excelBean.setAverage(finalAverage);
			excelBean.setDataType(actionCommand);
			excelBean.setEndDate(endDate);
			excelBean.setPolisherArm(sItemAvg.get(i).armID);
			excelBean.setStartDate(startDate);
			
			excelBeanLS.add(excelBean);
		}
		
		new ExcelExporter().generateParetoExcelData(excelBeanLS);

    }
	
	ArrayList<String> mapList = null;
	/*
	 * This ArrayList<String> mapList will contains all taper mapping name in such:
	 *	 Index	Station/Arm
	 *	  0		 1L
	 *	  1		 1R
	 *	  2		 2L
	 *	  3		 2R
	 *	  4		 3L
	 *	  5		 3R
	 *	  6		 4L
	 *	  7		 4R
	 *	  8		 5L
	 *	  9		 5R
	 *	 10		 6L
	 *	 11		 6R
	 *	 12		 7L
	 *	 13		 7R
	 */
	private String mapDCElement(String DCElement)
	{
		if(mapList == null)
		{
			mapList = new ArrayList<String>(14);
			for(int i=0; i<14; i++)
				mapList.add("");
			
			List<TaperMap>taperMapList = new DatabaseManager().listTaperMap();
			int index=0;
			for(TaperMap mapItem : taperMapList)
			{
				index = Integer.parseInt(mapItem.getStationName());
				if(index > 7)
					continue;
				index = (index -1) * 2;
				mapList.set(index, mapItem.getLeftTaper());
				mapList.set(index+1, mapItem.getRightTaper());				
			}
		}
				
		int index = mapList.indexOf(DCElement);
		
		int stationNo = (index / 2) + 1;
		char armNo = index%2 == 0? 'L': 'R';
		
		return stationNo+""+armNo;
	}

	private class AverageEntry
	{
		public String armID;
		public double average;
		public AverageEntry()
		{
			armID = "";
			average = 0;
		}
	}
	
	private class AvgEntryComparator implements Comparator
	{
		@Override
		public int compare(Object arg0, Object arg1) {
			AverageEntry target, item;
			if(arg0 instanceof AverageEntry && arg1 instanceof AverageEntry)
			{
				item = (AverageEntry)arg0;
				target = (AverageEntry)arg1;
			
				if(item.average == target.average)
					return 0;
				else if(item.average > target.average)
					return -1;
				else 
					return 1;	
			}
			else
				return -1;		
		}
	}
/**
 * END EXPORT TO EXCEL FUNCTIONALITY    
 * 
 **/
        private void exportToPDF() {
    	JFileChooser fc = new JFileChooser();
    	fc.setFileSelectionMode(0);
    	fc.setFileFilter(new SimpleFileFilter("pdf"));
    	
    	int returnVal = fc.showSaveDialog(this);
    	if (returnVal == 0) {
    		File file = fc.getSelectedFile();
    		
    		String path = file.getAbsolutePath();
    		
    		if (!path.endsWith(".pdf")) {
    		path = path + ".pdf";
    		}
    		
    		String finalPath = path;
    		try {
    			OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(finalPath)));
    			Rectangle pagesize = new Rectangle(842, 595);
    			Document document = new Document(pagesize, 50.0F, 50.0F, 50.0F, 50.0F);
    			try {
    				PdfWriter writer = PdfWriter.getInstance(document, out);
    				document.addAuthor("JFreeChart");
    				document.addSubject("Demonstration");
    				document.open();
    				PdfContentByte cb = writer.getDirectContent();
    				PdfTemplate tp = cb.createTemplate(842, 595);
    				Graphics2D g2 = tp.createGraphics(842, 595, new DefaultFontMapper());
    				Rectangle2D r2D = new Rectangle2D.Double(0.0D, 0.0D, 842, 595);

    				pcPnl.drawChart(g2, r2D);

    				g2.dispose();
    				cb.addTemplate(tp, 0.0F, 0.0F);
    			} catch (DocumentException de) {
    				System.err.println(de.getMessage());
    			}
    			document.close();
    			out.close();
                        
                        JOptionPane.showMessageDialog(null, "Graph successfully exported to PDF.", "Export Successfully", JOptionPane.PLAIN_MESSAGE);
    		}
    		catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
        
        public void addNotify() {
            super.addNotify();
            // Buffer
            createBufferStrategy(2);           
            //BufferStrategy strategy = getBufferStrategy();
        }
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        try {
			PropertiesLoader.getInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ParetoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ParetoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ParetoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ParetoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new ParetoFrame().setVisible(true);
            }
        });
    }
    /****************************************************************************
     * INTERNAL OPERATIONS : THE FRAME
     ****************************************************************************/
    
    /**
     * Prompts up a confirmation dialog to confirm the exit action.
     * Upon confirmation, dispose the frame.
     */
    private void onExit()
    {
        //remove the TendChart Panel
        pcPnl.setVisible(false);
        this.invalidate();
        this.validate();
        
        //reset all the values to default
        setInitData();
        
        //dispose the frame
        this.dispose();
    }
    
    /**
     * This is a hack for user to click on the 'x' button on window
     */
    protected void processWindowEvent(WindowEvent we)
    {
            if(we.getID() == WindowEvent.WINDOW_CLOSING)
                    onExit();
    }
    /****************************************************************************
     *  THE VARIABLES
     ****************************************************************************/
    // Variables declaration - do not modify
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JList jList1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton jbtDisplay;
    private javax.swing.JButton jbtExcel;
    private javax.swing.JButton jbtPDF;
    private com.toedter.calendar.JDateChooser jdcFromDate;
    private com.toedter.calendar.JDateChooser jdcToDate;
    private javax.swing.JRadioButton jrbRemoval;
    private javax.swing.JRadioButton jrbSTIR;
    private javax.swing.JRadioButton jrbTIR;
    private javax.swing.JRadioButton jrbTTV;
    private javax.swing.JRadioButton jrbTaper;
    Date dateFrom;
    SpinnerDateModel sdmFrom;
    JSpinner.DateEditor deFrom;
    private javax.swing.JSpinner jspFromTime;
    Date dateTo;
    SpinnerDateModel sdmTo;
    JSpinner.DateEditor deTo;
    private javax.swing.JSpinner jspToTime;
    private javax.swing.ButtonGroup rbgGraphType;
    // End of variables declaration
    DatabaseManager dm;
    private ParetoChartPanel pcPnl;
    List sList;
    int graphType;
}
